//
//  MainController.swift
//  6ccloud.com-iOS
//
//  Created by Daniel on 16/3/1.
//  Copyright © 2016年 Daniel. All rights reserved.
//

import UIKit

class MainController: UITableViewController, UIDocumentInteractionControllerDelegate, URLSessionDownloadDelegate {
    fileprivate var fileList:FileList?;
    fileprivate var alertQueue:Queue<UIAlertController> = Queue<UIAlertController>();
    internal var path:String = "/";
    fileprivate var downloadTask:URLSessionDownloadTask? = nil;
    fileprivate var downloadIndex:IndexPath? = nil;
    
    override func viewDidLoad() {
        self.tableView.register(UINib(nibName: "ItemCell", bundle: nil), forCellReuseIdentifier: "ItemCell");
        self.tableView.register(ItemCell.self, forCellReuseIdentifier: "itemCellClass");
        fileList = downloadFileList(self.path);
    }
    
    override func viewDidAppear(_ animated: Bool) {
        while (alertQueue.Count != 0) {
            self.present(alertQueue.Pop(), animated: true, completion: nil);
        }
        self.tabBarController?.tabBar.isHidden = false;
    }
    
    //TableView Data Source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fileList!.count;
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell;
        cell.loadImage(fileList![indexPath.row].Category == WebFile.TYPE_FOLDER);
        cell.itemName?.text = fileList![indexPath.row].Name;
        return cell;
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.tableView!.deselectRow(at: indexPath, animated: true);
        if (fileList![indexPath.row].Category == WebFile.TYPE_FOLDER) {
            //打开文件夹
            let newVC = MainController();
            newVC.title = fileList![indexPath.row].Name;
            newVC.path = fileList![indexPath.row].Path;
            newVC.tableView.rowHeight = self.tableView.rowHeight;
            self.navigationController?.pushViewController(newVC, animated: true);
        } else {
            //打开文件
            if (downloadTask == nil) {
                readFile(indexPath, complete: { (localFilePath) in
                    if (FileManager.default.fileExists(atPath: localFilePath)) {
                        let localUrl = URL(fileURLWithPath: localFilePath);
                        self.previewFile(localUrl);
                    } else {
                        self.showError("打开失败", message: "文件读取失败，请检查网络连接");
                    }
                });
            } else {
                if (downloadIndex != indexPath) {
                    self.showError("错误", message: "已经有正在下载的文件，不允许再尝试打开另一个文件！");
                }
            }
        }
    }
    
    
    
    
    //UIDocumentInteractionController Delegate Function
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self.navigationController!;
    }
    
    
    
    
    //NSURLSessionDownload Delegate Function
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        let data = try? Data(contentsOf: location)
        if (data != nil) {
            DispatchQueue.main.async {
                let key = self.fileList![(self.downloadIndex!.row)].Path;
                FileCache.write(key, data: data!);
                self.previewFile(FileCache.read(key)!);
            }
        } else {
            self.showError("下载失败", message: "没有接收到服务器的返回数据，请稍后重试！");
        }
        //Cleaning
        DispatchQueue.main.async {
            (self.tableView!.cellForRow(at: self.downloadIndex!) as! ItemCell).endDownload();
            self.downloadTask = nil;
            self.downloadIndex = nil;
        }
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        DispatchQueue.main.async {
            (self.tableView!.cellForRow(at: self.downloadIndex!) as! ItemCell).progressView.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite);
        }
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        DispatchQueue.main.async {
            if (error != nil && error!._code != -999) {
                self.showError("下载失败", message: error!.localizedDescription);
            }
            //Cleaning
            if (self.downloadIndex != nil) { //to prevent unnecessary clean after complete
                (self.tableView!.cellForRow(at: self.downloadIndex!) as! ItemCell).endDownload();
                self.downloadTask = nil;
                self.downloadIndex = nil;
            }
        }
    }
    
    
    
    
    //Tool Functions
    func downloadFileList(_ path: String) -> FileList {
        var params = Dictionary<String, String>();
        params["path"] = path;
        let response = ApiRequest.get(ApiRequest.LIST_FOLDER, params: params);
        if (response == nil) {
            showError("网络错误", message: "没有接收到服务器返回信息，请返回或退出重试");
            return self.fileList == nil ? FileList(files: NSDictionary()) : self.fileList!;
        }
        if (response?.object(forKey: "succ") == nil) {
            showError("数据解析错误", message: "没有收到规范的返回内容，请返回或退出重试");
            return self.fileList == nil ? FileList(files: NSDictionary()) : self.fileList!;
        }
        if (response?.object(forKey: "succ") as! String == "0") {
            showError("服务器错误", message: "服务器处理列表请求失败，请返回或退出重试");
            return self.fileList == nil ? FileList(files: NSDictionary()) : self.fileList!;
        }
        return FileList(files: response?.object(forKey: "msg") as! NSDictionary);
    }
    
    func showError(_ title: String, message: String) {
        let alert = UIAlertController.init(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert);
        alert.addAction(UIAlertAction(title: "确定", style: UIAlertActionStyle.cancel, handler: nil));
        if (self.isViewLoaded && (self.view.window != nil)) {
            self.present(alert, animated: true, completion: nil);
            self.tabBarController?.tabBar.isHidden = false;
        } else {
            alertQueue.Push(alert);
        }
    }
    
    func readFile(_ index: IndexPath, complete: (String) -> ()) {
        let row = index.row;
        let remotePath = fileList![row].Path;
        let localFilePath = FileCache.getCachePath(remotePath);
        //缓存策略
        let localMd5hash = FileMD5HashCreateWithPath(localFilePath as CFString, 4096);//It will be nil if the file doesn't exist
        var params = Dictionary<String, String>();
        params["path"] = remotePath;
        let remoteMd5Hash = ApiRequest.get(ApiRequest.FILE_CHECKSUM, params: params)?.object(forKey: "msg");
        //服务器没有响应文件MD5的验证请求时，尝试重新获取
        //在没有网络时直接尝试调用本地缓存
        if (localMd5hash == nil || remoteMd5Hash == nil || (remoteMd5Hash != nil && localMd5hash!.takeUnretainedValue() as String != remoteMd5Hash as! String)) {
            if (Reach().connectionStatus() != ReachabilityStatus.offline) {
                let session = Foundation.URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
                self.downloadTask = session.downloadTask(with: HttpRequest.getURL("http://download.6ccloud.com" + remotePath));
                //显示进度 & 允许取消
                (self.tableView!.cellForRow(at: index) as! ItemCell).startDownload();
                (self.tableView!.cellForRow(at: index) as! ItemCell).registerCancelButtonDownEvent({self.downloadTask?.cancel();});
                self.downloadIndex = index;
                self.downloadTask!.resume();
            }
        } else {
            complete(localFilePath); //done for reading cache
        }
    }
    
    func previewFile(_ localURL: URL) {
        let docInteractionVC = UIDocumentInteractionController(url: localURL);
        docInteractionVC.delegate = self;
        self.tabBarController!.tabBar.isHidden = true;
        let otherCanOpen:Bool = docInteractionVC.presentPreview(animated: true);
        if (!otherCanOpen) {
            self.showError("无法打开文件", message: "没有对应的应用程序可以打开此文件！");
        }
    }
}
